home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 August: Tool Chest / Dev.CD Aug 00 TC Disk 1.toast / pc / sample code / graphics 2d / makeicon / iconutil.c next >
Encoding:
C/C++ Source or Header  |  2000-06-23  |  8.0 KB  |  294 lines

  1. /*
  2.     File:        IconUtil.c
  3.  
  4.     Contains:    Routines to create icons of any pixel depth, and masked Icons.
  5.  
  6.     Written by: Brigham Stevens    
  7.  
  8.     Copyright:    Copyright © 1984-1999 by Apple Computer, Inc., All Rights Reserved.
  9.  
  10.                 You may incorporate this Apple sample source code into your program(s) without
  11.                 restriction. This Apple sample source code has been provided "AS IS" and the
  12.                 responsibility for its operation is yours. You are not permitted to redistribute
  13.                 this Apple sample source code as "Apple sample source code" after having made
  14.                 changes. If you're going to re-distribute the source, we require that you make
  15.                 it clear in the source that the code was descended from Apple sample source
  16.                 code, but that you've made changes.
  17.  
  18.     Change History (most recent first):
  19.                 7/9/1999    Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
  20.                 
  21.  
  22. */
  23.  
  24. #include <QDOffscreen.h>
  25. #include <Quickdraw.h>
  26. #include <Palettes.h>
  27. #include <Memory.h>
  28. #include <Resources.h>
  29. #include "OldBitMap.h"
  30. #include "MiscCode.h"
  31.  
  32. #include "IconUtil.h"
  33.  
  34. Handle MakeIconMask(GWorldPtr srcGWorld, Rect *srcRect, short iconSize)
  35. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  36.     this returns a handle to the image data for an icon MASK of dimension iconSize x iconSize.
  37.     The icon is created by copying the srcRect of srcGWorld into a PixMap.
  38.   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  39. {
  40.  
  41.     Handle    iconBits;
  42.     BitMap    srcBitMap,maskBitMap;
  43.     short    err;
  44.     long    numBytes;
  45.     short    rowbytes;
  46.     
  47.     iconBits = MakeIcon(srcGWorld, srcRect, 1, iconSize);
  48.     if(!iconBits)    return nil;
  49.     HLock(iconBits);
  50.  
  51.     srcBitMap.bounds = *srcRect;            // set up a plain jane bitmap
  52.     srcBitMap.rowBytes = iconSize/8;
  53.     srcBitMap.baseAddr = *iconBits;
  54.     
  55.     NewMaskedBitMap(&srcBitMap,&maskBitMap,srcRect);
  56.     if(!maskBitMap.baseAddr)
  57.     {
  58.         DisposeHandle(iconBits);
  59.         return nil;
  60.     }
  61.     
  62.     HUnlock(iconBits);
  63.  
  64.     CalcOffScreen(srcRect,&numBytes,&rowbytes);
  65.     err = PtrToXHand(maskBitMap.baseAddr,iconBits,numBytes);
  66.     if(err)
  67.     {
  68.         /* we can at least return a handle to the original image,
  69.             which may be considered better than nothing.
  70.             OR - we can dump the image and return nil.
  71.         */
  72.         DebugStr("\pERror in PtrToXHand");
  73.     }
  74.     
  75.     FreeBitMap(&maskBitMap);
  76.  
  77.     HNoPurge(iconBits);
  78.     return iconBits;
  79. }
  80.  
  81.  
  82. Handle    MakeICN_pound(GWorldPtr    gwp, Rect *srcRect, short iconDimension)
  83. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  84.     this returns a handle to the image data for an icon and it's mask, of size iconDimension x iconDimension.
  85.     The icon is created by copying the srcRect of srcGWorld into a PixMap.
  86.   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  87. {
  88.  
  89.     Handle    icon;
  90.     Handle    iconMask;
  91.     Size    iconSize;
  92.     
  93.     icon = MakeIcon(gwp, srcRect,1,iconDimension);            
  94.     
  95.     if(icon)
  96.     {
  97.         iconMask = MakeIconMask(gwp, srcRect, iconDimension);    
  98.         
  99.         if(iconMask)
  100.         {
  101.             iconSize = GetHandleSize(icon);
  102.             SetHandleSize(icon, iconSize + GetHandleSize(iconMask));
  103.             CheckError("\pSetHandleSize fail.",MemError());
  104.             BlockMove(*iconMask, (Ptr)(((long)*icon) + iconSize), GetHandleSize(iconMask));            
  105.             DisposeHandle(iconMask);
  106.         }
  107.  
  108.     }
  109.     
  110.     return icon;
  111.  
  112. }
  113.  
  114. Handle MakeIcon(GWorldPtr srcGWorld, Rect *srcRect, short dstDepth, short iconSize)
  115. /*
  116.     Creates a handle to the image data for an icon, or nil if an error.
  117.     The source image is specified by GWorld and regtangle defining the area
  118.     to create the icon from.
  119.     The type of icon is specified by the depth and Size paramters.
  120.     iconSize is used for both height and width.
  121.     For example, to create an Icl8 pass 8 for dstDepth and 32 for iconSize.
  122.     to create an ics8 pass 8 for the dstDepth and 16 for iconSize.
  123.     to create an ICON pass 1 for the dstDepth and 32 for iconSize.
  124.     
  125.     
  126. */
  127. {
  128.     GWorldPtr        saveWorld;
  129.     GDHandle        saveHandle;
  130.     long            bytesPerRow;
  131.     long            imageSize;
  132.     Handle            dstHandle;
  133.     PixMapHandle    pix;
  134.     Rect            iconFrame;
  135.     QDErr            err;
  136.     
  137.     GetGWorld(&saveWorld,&saveHandle);        // save Graphics env state
  138.  
  139.     SetGWorld(srcGWorld,nil);
  140.     
  141.     iconFrame.top = 0;
  142.     iconFrame.left = 0;
  143.     iconFrame.bottom = iconSize;
  144.     iconFrame.right = iconSize;
  145.     
  146.     // make a gworld for the icl resource
  147.     pix = (PixMapHandle)NewHandle(sizeof(PixMap));
  148.     
  149.     /* See Tech Note #120 - for info on creating a PixMap by hand as SetUpPixMap
  150.         does.  SetUpPixMap was taken from that Tech Note....
  151.     */
  152.     err =  SetUpPixMap(dstDepth,&iconFrame,GetCTable(dstDepth),pix);
  153.  
  154.     if(err)
  155.     {
  156.         //asm {move.w    err, d0 }
  157.         DebugStr("\pQuickDraw error.");
  158.         return nil;
  159.     }
  160.         
  161.     LockPixels(GetGWorldPixMap(srcGWorld));
  162.     LockPixels(pix);
  163.             
  164.     CopyBits((BitMapPtr)*srcGWorld->portPixMap,
  165.                 (BitMapPtr)*pix,
  166.                 srcRect,
  167.                 &iconFrame,
  168.                 srcCopy | ditherCopy, nil);
  169.  
  170.  
  171.     UnlockPixels(GetGWorldPixMap(srcGWorld));
  172.  
  173.      bytesPerRow = ((dstDepth * ((**pix).bounds.right - (**pix).bounds.left) + 31) / 32) * 4;
  174.     imageSize  = (bytesPerRow) * ((**pix).bounds.bottom - (**pix).bounds.top);
  175.  
  176.     dstHandle = NewHandle(imageSize);
  177.     err = MemError ();
  178.     if(err || dstHandle == nil)
  179.     {
  180.         //asm { move.w err, d0}
  181.         DebugStr("\pI am fuckered.");
  182.         return nil;    
  183.     }
  184.     HLock((Handle)dstHandle);
  185.     BlockMove(GetPixBaseAddr(pix),*dstHandle,imageSize);
  186.     HUnlock(dstHandle);
  187.     UnlockPixels(pix);
  188.     TearDownPixMap(pix);
  189.     // Restore graphics env to previous state
  190.     SetGWorld(saveWorld,saveHandle);
  191.     
  192.     HNoPurge(dstHandle);
  193.     return dstHandle;
  194. }
  195.  
  196.  
  197. void TearDownPixMap(PixMapHandle pix)
  198. {
  199.     // We really need to do more....  BUT It is the thought that counts.. 
  200.     DisposeHandle((Handle)pix);    
  201. }
  202.  
  203.  
  204. #include <QDOffscreen.h>
  205. #include <Palettes.h>
  206.  
  207. PicHandle PIXtoPICT(CGrafPtr wp)
  208. {
  209.     PicHandle        pict;                // this is the Picture we give back
  210.     WindowPtr        saveWindow;            // for saving the port
  211.     
  212.     GetPort(&saveWindow);                // set up the ports so we can 
  213.     SetPort((GrafPort*)wp);                        //  - copy and have a palette too
  214.  
  215.     pict = OpenPicture(&wp->portRect);    // open a picture, this disables drawing
  216.     if(!pict)    return nil;
  217.     
  218.     CopyBits((BitMapPtr)*wp->portPixMap,            // src PixMap    - we copy image over itself -
  219.                 (BitMapPtr)*wp->portPixMap,        // dst PixMap    - no drawing occurs -
  220.                 &wp->portRect,            // srcRect        - it will be recorded and compressed -
  221.                 &wp->portRect,            // dstRect        - into the picture that is open -
  222.                 srcCopy,nil);            // copyMode and no clip region
  223.  
  224.     ClosePicture();                        // We are done recording the picture
  225.     SetPort(saveWindow);                // restore to the previous port
  226.     return pict;                        // return our groovy pict handle
  227. }
  228.  
  229. GWorldPtr LoadPictToGWorld(int resID, WindowPtr wp, int numEntries,
  230.                         int pdepth, int gdepth, Boolean linkCtabToPal)
  231.                         
  232. /*
  233.     Loads in the picture specified be the resID parameter.
  234.     Creates a GWorld from characteristics of window wp
  235.     Stores the GWorld pointer in the wRefcon field of the windowRecord.
  236. */
  237. {
  238.  
  239.     CTabHandle        gwctab;
  240.     WindowPtr        saveWindow;
  241.     GDHandle        saveDevice;
  242.     PicHandle        pict;
  243.     Rect            destRect;
  244.     short            i;
  245.     PaletteHandle     pal;
  246.     GWorldPtr         gw;    
  247.  
  248.     pict = GetPicture(resID);
  249.     if(!pict)
  250.         DebugStr("\pError - pict was nil!");
  251.     destRect = (**pict).picFrame;
  252.     OffsetRect( &destRect, -destRect.left, -destRect.top );
  253.     SizeWindow(wp, destRect.right, destRect.bottom,true);
  254.  
  255.     pal = NewPalette(numEntries, GetCTable(pdepth), pmTolerant, 0);
  256.     SetPalette(wp, pal, true);
  257.  
  258.     gw = (GWorldPtr)CreateOffScreen(wp, gdepth, false);    // make a gworld
  259.  
  260.     if(linkCtabToPal)
  261.     {
  262.         gwctab = (**GetGWorldPixMap(gw)).pmTable;    // get the color table for the gWorld.
  263.     
  264.         // Set up the clut so that the entries refer to palette
  265.         // indexes, instead of the usual rgb information.
  266.         (**gwctab).ctFlags |= 0x4000;        // this bit is the flag to indicate this
  267.         //•••••••• See Inside Macintosh Volume VI page 20-17
  268.         
  269.         for (i = 0; i <= (**gwctab).ctSize; i++)
  270.         {
  271.             (**gwctab).ctTable[i].value = i;
  272.         }
  273.         CTabChanged(gwctab);        // Update the color table
  274.     }    
  275.     
  276.     GetGWorld((CGrafPort**)&saveWindow,&saveDevice);
  277.     SetGWorld(gw,nil);
  278.  
  279.     // draw the picture into the offscreen gworld
  280.     pict = GetPicture(resID);
  281.     
  282.     if(LockPixels (GetGWorldPixMap (gw)))
  283.     {
  284.         DrawPicture(pict,&destRect);
  285.         UnlockPixels(GetGWorldPixMap(gw));
  286.     }
  287.     SetGWorld((CGrafPort*)saveWindow,saveDevice);
  288.     SetWRefCon(wp,(long)gw);                    // store gWold in refcon of Window
  289.     ReleaseResource((Handle)pict);
  290.     
  291.     return gw;
  292. }
  293.  
  294.